package com.yuke.cloud.service.pmc.service.impl;

import com.github.pagehelper.PageHelper;
import com.yuke.cloud.common.base.enums.ErrorCodeEnum;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.service.api.omc.exceptions.OmcBizException;
import com.yuke.cloud.service.api.omc.service.OmcOrderFeignApi;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecInfoDto;
import com.yuke.cloud.service.api.smc.service.SmcFeignApi;
import com.yuke.cloud.service.pmc.dao.ProdMainAttributeMapper;
import com.yuke.cloud.service.pmc.dao.ProdProductMapper;
import com.yuke.cloud.service.pmc.dto.*;
import com.yuke.cloud.service.pmc.entity.*;
import com.yuke.cloud.service.pmc.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * Created by zys on 2018/09/27.
 */
@Slf4j
@Service
@Transactional
public class ProdProductServiceImpl extends BaseService<ProdProduct> implements ProdProductService {
    @Resource
    private ProdProductMapper prodProductMapper;
    @Resource
    private ProdSpecService prodSpecService;
    @Resource
    private ProdSpecPictureService prodSpecPictureService;
    @Resource
    private ProdSpecAttributeService prodSpecAttributeService;
    @Resource
    private ProdCategoryService prodCategoryService;
    @Resource
    private ProdCategoryAttributeService prodCategoryAttributeService;
    @Resource
    private SmcFeignApi smcFeignApi;
    @Resource
    private OmcOrderFeignApi omcOrderFeignApi;
    @Resource
    private ProdMainAttributeMapper prodMainAttributeMapper;

    @Override
    public List<ProdProductInfoDto> getListsByCondition(ConditionDto conditionDto, Integer page, Integer size) {
        List<Long> leafCategoryIds = new ArrayList<>();
        if (conditionDto.getCategoryId() == 0L) {
            leafCategoryIds = prodCategoryService.findAll().stream().map(ProdCategory::getCategoryId).collect(Collectors.toList());
        } else {
            prodCategoryService.leafCategoryId(conditionDto.getCategoryId(), leafCategoryIds);
        }
        if (leafCategoryIds.size() == 0) {
            log.info("getListsByCondition()方法, categoryId = {} is error", conditionDto.getCategoryId());
            return null;
        }
        return  getProdProductInfoDtos(leafCategoryIds,conditionDto,page,size);
    }

    private List<ProdProductInfoDto> getProdProductInfoDtos(List<Long> leafCategoryIds ,ConditionDto conditionDto,Integer page, Integer size){
        PageHelper.startPage(page, size);
        List<ProdProductInfoDto> prodProductInfoDtos = prodProductMapper.getListsByCondition(leafCategoryIds, conditionDto);
        return prodProductInfoDtos;
    }

    @Override
    public ProdProductDto getProdByProductId(Long productId) {
        ProdProductDto prodProductDto = new ProdProductDto();
        ProdProduct prodProduct = prodProductMapper.selectProductByProductId(productId);
        List<ProdCategoryAttributeDto> prodCategoryAttributeDtos = prodCategoryAttributeService.getEnableBindByCategoryId(prodProduct.getCategoryId());

        // 获取商品主属性
        List<Long> mainAttributeList = new ArrayList<>();
        Example example = new Example(ProdMainAttribute.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productId", productId);
        List<ProdMainAttribute> listProdMainAttribute = prodMainAttributeMapper.selectByExample(example);
        if (listProdMainAttribute != null && listProdMainAttribute.size() > 0) {
            for (ProdMainAttribute prodMainAttribute : listProdMainAttribute) {
                mainAttributeList.add(prodMainAttribute.getAttributeId());
            }
        }
        prodProduct.setMainAttributeList(mainAttributeList);
        prodProductDto.setProdProduct(prodProduct);
        List<ProdSpecDto> prodSpecDtos = prodProductMapper.getProdSpecsByProductId(productId);
        for (ProdSpecDto prodSpec:prodSpecDtos) {
            List<Long> list = new ArrayList<>();
            list.add(prodSpec.getProdSpec().getSpecId());
            List<ProdSpecPicture> prodSpecPictures = prodSpecPictureService.getProdSpecPicBySpecIds(list);
            List<ProdSpecAttribute> prodSpecAttributes = prodSpecAttributeService.getProdSpecAttrBySpecId(prodSpec.getProdSpec().getSpecId());
            prodSpec.setProdSpecPictures(prodSpecPictures);
            prodSpec.setProdSpecAttributes(prodSpecAttributes);
            prodSpec.setProdCategoryAttributeDtos(prodCategoryAttributeDtos);
        }
        prodProductDto.setProdSpecDtos(prodSpecDtos);
        return prodProductDto;
    }

    @Override
    public List<ProdProduct> getListByCondition(ProdProduct prodProduct) {
        return prodProductMapper.getListByCondition(prodProduct);
    }

    @Override
    public void updateBySpecId(ProdProduct prodProduct, List<ProdSpecDto> prodSpecDtos) {
        Long oldCategoryId = prodProductMapper.selectByPrimaryKey(prodProduct.getProductId()).getCategoryId();

        // 更新商品主属性关联表
        // 先删除记录然后添加
        Example exampleMainAttr = new Example(ProdMainAttribute.class);
        Example.Criteria criteriaMainAttr = exampleMainAttr.createCriteria();
        criteriaMainAttr.andEqualTo("productId", prodProduct.getProductId());
        prodMainAttributeMapper.deleteByExample(exampleMainAttr);
        // 保存商品主属性
        List<Long> mainAttributeList = prodProduct.getMainAttributeList();
        if (mainAttributeList != null && mainAttributeList.size() > 0) {
            for (Long mainAttribute : mainAttributeList) {
                ProdMainAttribute prodMainAttribute = new ProdMainAttribute();
                prodMainAttribute.setMainAttributeId(generateId());
                prodMainAttribute.setProductId(prodProduct.getProductId());
                prodMainAttribute.setAttributeId(mainAttribute);
                prodMainAttributeMapper.insertSelective(prodMainAttribute);
            }
        }

        if (prodSpecDtos != null && prodSpecDtos.size() > 0) {
            for (ProdSpecDto prodSpecDto : prodSpecDtos) {
                prodSpecService.update(prodSpecDto.getProdSpec());

                List<ProdSpecAttribute> prodSpecAttributes = prodSpecDto.getProdSpecAttributes();

                if (!prodProduct.getCategoryId().equals(oldCategoryId)) {
                    //如果分类修改了，则以前该商品规格属性全部删除
                    ProdSpecAttribute prodSpecAttribute = new ProdSpecAttribute();
                    prodSpecAttribute.setSpecId(prodSpecDto.getProdSpec().getSpecId());
                    prodSpecAttributeService.delete(prodSpecAttribute);

                    for (ProdSpecAttribute attribute : prodSpecAttributes) {
                        attribute.setSpecId(prodSpecDto.getProdSpec().getSpecId());
                        prodSpecAttributeService.save(attribute);

                    }
                }else{

                    for (ProdSpecAttribute prodSpecAttribute : prodSpecAttributes) {
                        prodSpecAttribute.setSpecId(prodSpecDto.getProdSpec().getSpecId());
                        if (null == prodSpecAttribute.getSpecAttributeId() || "".equals(prodSpecAttribute.getSpecAttributeId().toString())) {
                            prodSpecAttributeService.save(prodSpecAttribute);
                        } else {
                            prodSpecAttributeService.update(prodSpecAttribute);
                        }
                    }
                }

                List<ProdSpecPicture> prodSpecPictures = prodSpecDto.getProdSpecPictures();
                for (ProdSpecPicture prodSpecPicture : prodSpecPictures) {
                    prodSpecPicture.setSpecId(prodSpecDto.getProdSpec().getSpecId());
                    if (null == prodSpecPicture.getSpecPictureId() || "".equals(prodSpecPicture.getSpecPictureId().toString())) {
                        //新加的图片记录
                        prodSpecPictureService.save(prodSpecPicture);
                    } else {
                        if (prodSpecPicture.getOldBigPicUri() != null && prodSpecPicture.getOldSmallPicUri()!= null) {
                            //说明该图片已经被删除，同时需要删除该条记录
                            prodSpecPictureService.delete(prodSpecPicture);
                        }

                        //需要更新的图片记录
//                if (prodSpecPicture.getBigPicUri() == null && prodSpecPicture.getSmallPicUri() == null) {
//                    //说明该图片已经被删除，需要删除该条记录
//                    prodSpecPictureService.delete(prodSpecPicture);
//                } else {
//                    prodSpecPictureService.update(prodSpecPicture);
//                }

                        // add by wg 20190515 更新图片记录
                        if (prodSpecPicture.getOldBigPicUri() == null && prodSpecPicture.getOldSmallPicUri() == null) {
                            Example example = new Example(ProdSpecPicture.class);
                            Example.Criteria criteria = example.createCriteria();
                            criteria.andEqualTo("specPictureId", prodSpecPicture.getSpecPictureId());
                            prodSpecPictureService.updateByExample(prodSpecPicture, example);
                        }

                    }
                }
            }
        }

        this.update(prodProduct);
    }

    @Override
    public void saveAllInfo(ProdProduct prodProduct, List<ProdSpecDto> prodSpecDtos) {
        this.save(prodProduct);
        this.saveUpdateInfo(prodProduct, prodSpecDtos);
    }

    @Override
    public void saveUpdateInfo(ProdProduct prodProduct, List<ProdSpecDto> prodSpecDtos) {
        for (ProdSpecDto prodSpecDto : prodSpecDtos) {
            ProdSpec prodSpec = prodSpecDto.getProdSpec();
            prodSpec.setProductId(prodProduct.getProductId());
            prodSpecService.save(prodSpec);
            long prodSpecId = prodSpec.getSpecId();
            prodSpecDto.getProdSpecPictures().forEach(prodSpecPicture -> {
                prodSpecPicture.setSpecId(prodSpecId);
                prodSpecPictureService.save(prodSpecPicture);
            });
            prodSpecDto.getProdSpecAttributes().forEach(prodSpecAttribute -> {
                prodSpecAttribute.setSpecId(prodSpecId);
                prodSpecAttributeService.save(prodSpecAttribute);
            });
        }
    }

    @Override
    public List<ProdSpecInfoAndPriceDto> getProdByCategoryId(Long categoryId) {
        log.info("--- Enter getProdByCategoryId(Long categoryId) : {} ---",categoryId);
        List<Long> leafCategoryIds = new ArrayList<>();
        prodCategoryService.leafCategoryId(categoryId, leafCategoryIds);
        if (leafCategoryIds.size() == 0) {
            log.info("--- Leave getProdByCategoryId(Long categoryId), categoryId={} is error ---", categoryId);
            return null;
        }
        List<ProdSpecInfoAndPriceDto> prodProducts = prodProductMapper.ProdSpecInfoAndPriceByCategoryIds(leafCategoryIds);
        if (prodProducts.size() == 0) {
            log.info("--- Leave getProdByCategoryId(Long categoryId), leafCategoryIds={}分类下没有商品 ---", leafCategoryIds);
            return null;
        }

        List<Long> specIds = prodProducts.stream().map(ProdSpecInfoAndPriceDto::getSpecId).collect(Collectors.toList());

        List<Map> list = omcOrderFeignApi.countnum(specIds);
        if (list == null) {
            log.error("--- Leave getProdByCategoryId(Long categoryId), omcOrderFeignApi.countnum(specIds)内部异常，参数：{};返回值：{} ---", specIds,list);
            throw new OmcBizException(ErrorCodeEnum.GL99990002);
        }
        for (ProdSpecInfoAndPriceDto prodSpecInfoAndPriceDto : prodProducts) {

            for (Map map : list) {
                if (prodSpecInfoAndPriceDto.getSpecId().equals(Long.parseLong(map.get("specId").toString()))) {
                    prodSpecInfoAndPriceDto.setSaleCount(Long.parseLong(map.get("nums").toString()));
                }
            }
        }
        prodProducts = prodProducts.stream().filter(prodSpecInfoAndPriceDto -> prodSpecInfoAndPriceDto.getSalePrice() != null).collect(Collectors.toList());
        log.info("--- Leave getProdByCategoryId(Long categoryId), 返回值大小：{} ---", prodProducts.size());

        return prodProducts;
    }

    @Override
    public List<ProdSpecInfoAndPriceDto> getProdByRegionId(Long regionId) {
        List<ProdSpecInfoAndPriceDto> prodSpecInfoAndPriceDtos = prodProductMapper.getSpecInfoByRegionId(regionId);
        if (prodSpecInfoAndPriceDtos.size() == 0) {
            return null;
        }

        return prodSpecInfoAndPriceDtos.stream().filter(prodSpecInfoAndPriceDto -> prodSpecInfoAndPriceDto.getSalePrice() != null).collect(Collectors.toList());
    }

    @Override
    public List<ProdSpecInfoDto> getProdNameByProductId(List<Long> productIds) {
        return prodProductMapper.getProdNameByProductId(productIds);
    }

    @Override
    public void deleteByProductId(Long productId) {
        prodProductMapper.deleteByProductId(productId);
    }

    private List<Long> getSpecIdsByCategoryId(Long categoryId) {
        List<Long> spedIds = new ArrayList<>();
        List<Long> leafCategoryIds = new ArrayList<>();
        prodCategoryService.leafCategoryId(categoryId, leafCategoryIds);
        if (leafCategoryIds.size() == 0) {
            return null;
        }
        spedIds = prodSpecService.getEnableSpecByCategoryIds(leafCategoryIds).stream().map(ProdSpec::getSpecId).collect(Collectors.toList());
        return spedIds;
    }

    @Override
    public int save(ProdProduct record) {
        record.setProductId(generateId());

        // 保存商品主属性
        List<Long> mainAttributeList = record.getMainAttributeList();
        if (mainAttributeList != null && mainAttributeList.size() > 0) {
            for (Long mainAttribute : mainAttributeList) {
                ProdMainAttribute prodMainAttribute = new ProdMainAttribute();
                prodMainAttribute.setMainAttributeId(generateId());
                prodMainAttribute.setProductId(record.getProductId());
                prodMainAttribute.setAttributeId(mainAttribute);
                prodMainAttributeMapper.insertSelective(prodMainAttribute);
            }
        }

        return super.save(record);
    }


}
